<?php
declare (strict_types=1);

namespace app\common\tool;

class Redis
{
    public $redis;

    public $prefix = 'Tp8_';

    public function __construct()
    {
        $this->redis = new \Redis();
        $this->redis->connect('127.0.0.1');
    }

    public function set($key, $value, $time = 0)
    {
        if (!$key) {
            return '';
        }
        $key = $this->prefix . $key;
        if (is_array($value)) {
            $value = json_encode($value);
        }
        if (!$time) {
            return $this->redis->set($key, $value);
        }

        return $this->redis->setex($key, $time, $value);
    }

    public function get($key)
    {
        if (!$key) {
            return '';
        }
        $key = $this->prefix . $key;
        return $this->redis->get($key);
    }

    public function incr($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->incr($key);
    }

    public function incrBy($key, $value = 1)
    {
        $key = $this->prefix . $key;
        return $this->redis->incrBy($key, $value);
    }

    public function decr($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->decr($key);
    }

    public function decrBy($key, $value = 1)
    {
        $key = $this->prefix . $key;
        return $this->redis->decrBy($key, $value);
    }

    public function del($key)
    {
        if (!$key) {
            return '';
        }
        $key = $this->prefix . $key;
        if (is_array($key)) {
            foreach ($key as $va) {
                $this->redis->del($va);
            }
            return true;
        }
        return $this->redis->del($key);
    }

    /**
     * 集合操作，保证数据的唯一，不保证顺序
     */
    /**
     * @param $key
     * @param $val
     * @return int
     * 集合添加
     */
    public function sAdd($key, $val)
    {
        $key = $this->prefix . $key;
        return $this->redis->sAdd($key, $val);
    }

    /**
     * @param $key
     * @param $val
     * @return int
     * 删除集合中指定的一个元素，元素不存在返回0。删除成功返回1，否则返回0。
     */
    public function sRem($key, $val)
    {
        $key = $this->prefix . $key;
        return $this->redis->sRem($key, $val);
    }

    /**
     * @param $key
     * @return array
     *smembers 返回集合中的所有成员
     */
    public function sMembers($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->sMembers($key);
    }

    /**
     * @param $key
     * @param $val
     * @return bool
     * 判断集合里是否存在指定元素，是返回true，否则返回false。
     */
    public function sismember($key, $val)
    {
        $key = $this->prefix . $key;
        return $this->redis->sismember($key, $val);
    }

    /**
     * @param $key
     * @return int
     * 返回集合中元素的数量。
     */
    public function sCard($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->sCard($key);
    }

    /**
     * Hash哈希操作可理解为数据库操作
     */
    /**
     * @param $key
     * @param $hashKey
     * @param $value
     * @return bool|string
     * hash表存
     */
    public function hSet($key, $hashKey, $value)
    {
        if (!$key || !$hashKey || !$value) {
            return '';
        }
        $key = $this->prefix . $key;
        if (is_array($value)) {
            foreach ($value as $k => $v) {
                $this->redis->hSet($key, $hashKey, $v);
            }
            return true;
        }

        return $this->redis->hSet($key, $hashKey, $value);
    }

    /**
     * @param $key
     * @param $hashKey
     * @return string
     * 获取表中指定字段的值。若表不存在则返回false。
     */
    public function hGet($key, $hashKey)
    {
        $key = $this->prefix . $key;
        return $this->redis->hGet($key, $hashKey);
    }

    /**
     * @param $key
     * @return array
     * 获取表所有的字段和值。
     */
    public function hGetAll($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->hGetAll($key);
    }

    /**
     * @param $key
     * @return array
     * 获取表所有字段名。表不存在时返回空数组，key不为表时返回false。
     */
    public function hKeys($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->hKeys($key);
    }

    /**
     * @param $key
     * @return array
     * 获取表所有字段值
     */
    public function hVals($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->hVals($key);
    }

    public function hIncrBy($key, $hashKey, $value)
    {
        $key = $this->prefix . $key;
        $is = $this->hExists($key, $hashKey);
        if ($is) {
            return $this->redis->hIncrBy($key, $hashKey, $value);
        } else {
            return $this->hSet($key, $hashKey, $value);
        }

    }

    /**
     * @param $key
     * @param $hashKey
     * @return bool
     * 查看表的某个字段是否存在，存在返回true，否则返回false。
     */
    public function hExists($key, $hashKey)
    {
        $key = $this->prefix . $key;
        return $this->redis->hExists($key, $hashKey);
    }

    /**
     * @param $key
     * @return int
     * 获取表的字段数量。若表不存在返回0，若不是hash表则返回false
     */
    public function hLen($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->hLen($key);
    }

    /**
     * @param $key
     * @param $hashKey
     * @return bool
     * 删除表的字段
     */
    public function hDel($key, $hashKey)
    {
        $key = $this->prefix . $key;
        if (is_array($hashKey)) {
            foreach ($key as $va) {
                $this->redis->hDel($key, $va);
            }
            return true;
        }

        return $this->redis->hDel($key, $hashKey);
    }

    /**
     * List列表操作,可理解为数组操作插入、删除数据,按照一定规律排列的元素,可重复适用于队列
     */

    /**
     * @param $key
     * @param $val
     * @return bool|int
     * 从最左插入，或者从头部插入，可以理解为左入
     */
    public function lPush($key, $val)
    {
        $key = $this->prefix . $key;
        if (is_array($val)) {
            foreach ($val as $v) {
                $this->redis->lPush($key, $v);
            }
            return true;
        }

        return $this->redis->lPush($key, $val);
    }

    /**
     * @param $key
     * @param $val
     * @return bool|int
     * 从最右插入，或者从尾部插入，可以理解为右入
     */
    public function rPush($key, $val)
    {
        $key = $this->prefix . $key;
        if (is_array($val)) {
            foreach ($val as $v) {
                $this->redis->rPush($key, $v);
            }
            return true;
        }

        return $this->redis->rPush($key, $val);
    }

    /**
     * @param $key
     * @return bool|string
     * 移除列表中第一个元素，可以理解为移除列表中最左边的元素，可以称为左出对应右入
     */
    public function lPop($key)
    {
        if (!$key) {
            return false;
        }
        $key = $this->prefix . $key;
        return $this->redis->lPop($key);
    }

    /**
     * @param $key
     * @return bool|string
     * 移除列表中最后一个元素，可以理解为移除列表中最右边的元素，可以称为右出对应左入
     */
    public function rPop($key)
    {
        if (!$key) {
            return false;
        }
        $key = $this->prefix . $key;
        return $this->redis->rPop($key);
    }

    /**
     * @param $key
     * @return bool|int
     * 返回列表的长度
     */
    public function lLen($key)
    {
        if (!$key) {
            return false;
        }
        $key = $this->prefix . $key;
        return $this->redis->lLen($key);
    }

    /**
     * @param $key
     * @param $index
     * @return String
     * 通过索引获取列表中的元素，如果没有该索引，则返回false。
     */
    public function lindex($key, $index)
    {
        $key = $this->prefix . $key;
        return $this->redis->lindex($key, $index);
    }

    public function lRem($key, $value, $count = 0)
    {
        $key = $this->prefix . $key;
        return $this->redis->lRem($key, $value, $count);
    }

    /**
     * @param $key
     * @return array
     * 返回列表中的所有元素
     */
    public function lrange($key)
    {
        $key = $this->prefix . $key;
        return $this->redis->lrange($key, 0, -1);
    }

    public function flushAll()
    {
        return $this->redis->flushAll();
    }
}